<!--
 @description 折线图公共组件（基于zengqiongying老师的折线图组件做修改，满足同一页面使用多个折线图动态传送图表数据渲染视图）
 @fileName LineChart.vue
 @author maliang
 @created 2021/09/26 14:05:00
-->
<template>
  <div>
    <div class="trend-box">
      <div :id="chartId" ref="myEchart" class="echart_container" />
    </div>
  </div>
</template>

<script>
import { v4 as uuidv4 } from 'uuid'
export default {
  name: 'LineChart',
  props: {
    xAxisData: {
      type: Array,
      default: () => {
        return null
      }
    },
    seriesData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 是否显示百分比
    percentage: {
      type: Boolean,
      default: false
    },
    showLegend: {
      type: Boolean,
      default: true
    },
    axisLabelRotate: {
      type: Number,
      default: 0
    },
    symbolSize: {
      type: Number,
      default: 6
    },
    gridData: {
      type: Object,
      default: () => {
        return null
      }
    }
  },
  data() {
    const _this = this
    return {
      windowSize: [0, 0],
      chartId: `echart-line-${uuidv4()}`, // 用UUID生成图表id，防止id重复
      chart: { map: null, chartData: [] },
      shadowColors: {
        '#12B9A3': 'rgba(18, 185, 163, .4)',
        '#FEB81D': 'rgba(254, 184, 29, .4)',
        '#3D98F1': 'rgba(61, 152, 241, .4)',
        '#F15643': 'rgba(241, 86, 67, .4)'
      },
      chartColors: [], // 自定义图列颜色集合
      echartOption: {
        title: {
          text: '折线图',
          show: false
        },
        color: ['#12B9A3', '#FEB81D', '#3D98F1', '#F15643'], // 绿黄蓝红
        tooltip: {
          trigger: 'axis',
          textStyle: {
            color: '#333333',
            fontFamily: 'PFZH',
            fontSize: 12,
            lineHeight: 26
          },
          axisPointer: {
            type: 'line',
            lineStyle: {
              type: 'solid',
              color: '#FFD5CB',
              width: 2,
              shadowBlur: 16,
              shadowColor: '#F15643',
              shadowOffsetX: 0,
              shadowOffsetY: 0
            }
          },
          extraCssText: 'z-index: 9', // 设置层级
          formatter(params) {
            let tipMsg = `时间: ${params[0].name}<br>`
            for (const i in params) {
              const item = params[i]
              tipMsg += `${item.seriesName}: <span style="color:${
                item.color
              }">${_this.foramtThousand(
                Number(item.data).toFixed(2)
              )}</span> <br>`
            }
            return `<div class="echart-tooltip-content">${tipMsg}</div>`
          }
        },
        legend: {
          data: [], // ['今年', '去年'],
          show: _this.showLegend,
          align: 'left',
          left: 0,
          top: 0,
          itemWidth: 12, // 图例图标的宽
          itemHeight: 12, // 图例图标的高
          padding: [0, 0, 5, 5],
          // icon: "square", // 图例的形状
          lineStyle: {
            opacity: 0
          },
          textStyle: {
            color: '#888888',
            fontFamily: 'PFZH'
          }
        },
        grid: {
          left: '5',
          right: '10',
          bottom: '0',
          top: '40',
          containLabel: true,
          show: false
        },
        toolbox: {
          show: false,
          feature: {
            saveAsImage: {}
          }
        },
        xAxis: {
          type: 'category',
          // boundaryGap: false, // x轴左右留白
          boundaryGap: ['10%', '10%'],
          data: [],
          axisLine: {
            show: false
          },
          axisTick: {
            show: false // x轴刻度隐藏
          },
          axisLabel: {
            rotate: _this.axisLabelRotate, // x轴文字倾斜度
            fontSize: _this.axisLabelRotate > 0 ? 10 : 12,
            // 坐标轴字体颜色
            color: '#CCCCCC',
            formatter: (value) => {
              return value.substring(
                value.indexOf('-') + 1,
                value.length
              )
            }
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            // 坐标轴字体颜色
            color: '#CCCCCC'
          }
        },
        series: []
      },
      seriesItem: {
        name: '今年',
        type: 'line',
        smooth: true, // 是否平滑曲线显示
        symbolSize: _this.symbolSize,
        lineStyle: {
          color: '#12B9A3', // 绿色
          // width: 2,
          shadowBlur: 2,
          shadowColor: 'rgba(18, 185, 163, .4)',
          shadowOffsetX: 0,
          shadowOffsetY: 8
        },
        tooltip: {
          textStyle: {
            color: '#12B9A3'
          }
        },
        data: []
      },
      initChartFinish: false // 图表初始化是否完成
    }
  },
  computed: {
    // 是否开始绘制地图（监听数据获取完成、图表初始化完成后绘制地图）
    isStartDrawChart() {
      if (this.xAxisData && this.initChartFinish) {
        return true
      }
      return false
    }
  },
  watch: {
    isStartDrawChart: {
      handler(val) {
        if (val) {
          this.resetChartData() // 数据处理
        } else {
          this.chart.map.clear()
          this.showLoading()
        }
      }
    },
    windowSize(val, oldVal) {
      this.chart.map.resize()
    }
  },
  created() {
    if (this.chartColors && this.chartColors.length) {
      this.$set(this.echartOption, 'color', this.chartColors)
    }
    if (this.legendData && this.legendData.length) {
      const seriesConfig = []
      this.legendData.forEach((name, index) => {
        const color = this.echartOption.color[index] || '' // 颜色
        const shadowColor = this.shadowColors[color] || '' // 阴影
        const lineStyle = {
          ...this.seriesItem.lineStyle,
          ...{ color, shadowColor }
        }
        const tooltip = {
          ...this.seriesItem.tooltip,
          ...{ textStyle: { color }}
        }
        const seriesItem = {
          ...this.seriesItem,
          ...{ name, lineStyle, tooltip }
        }
        seriesConfig.push(seriesItem)
      })
      this.$set(this.echartOption, 'series', seriesConfig)
      this.$set(this.echartOption.legend, 'data', this.legendData)
    }
    if (this.gridData) {
      this.echartOption.grid = Object.assign(
        this.echartOption.grid,
        this.gridData
      )
    }
  },
  mounted() {
    this.initChart()
  },
  methods: {
    resetChartData() {
      this.echartOption.xAxis.data = this.xAxisData
      const seriesData = []
      this.echartOption.series = []
      this.echartOption.legend.data = []
      this.seriesData.forEach((item, index) => {
        const seriesItem = JSON.parse(JSON.stringify(this.seriesItem))
        seriesItem.lineStyle.color = this.echartOption.color[index]
        seriesItem.data = item.data
        seriesItem.name = item.name
        seriesData.push(seriesItem)
        this.echartOption.legend.data.push(item.name)
      })
      this.echartOption.series = seriesData
      this.drawChart()
    },
    initChart() {
      if (this.percentage) {
        this.echartOption.yAxis.axisLabel.formatter = '{value}%'
        this.echartOption.tooltip.formatter = (params) => {
          let tipMsg = `时间: ${params[0].name}<br>`
          for (const i in params) {
            const item = params[i]
            tipMsg += `${item.seriesName}: <span style="color:${
              item.color
            }">${this.foramtThousand(
              Number(item.data).toFixed(2)
            )}%</span> <br>`
          }
          return `<div class="echart-tooltip-content">${tipMsg}</div>`
        }
      }

      this.windowSize = [
        document.body.clientWidth,
        document.body.clientHeight
      ]
      window.addEventListener('resize', () => {
        this.windowSize = [
          document.body.clientWidth,
          document.body.clientHeight
        ]
      })
      this.chart.map = this.$echarts.init(
        document.getElementById(this.chartId)
      )
      window.onresize = () => {
        this.chart.map.resize()
      }
      this.showLoading()
      this.initChartFinish = true
    },
    async drawChart() {
      if (this.chart.map) {
        this.chart.map.dispatchAction({
          type: 'hideTip'
        })
      }
      this.chart.map.hideLoading() // 数据获取完成后隐藏loading
      this.chart.map.clear()
      this.chart.map.setOption(this.echartOption)

      this.$nextTick(() => {
        setTimeout(() => {
          this.chart.map.resize()
        }, 300)
      })

      // 高亮时触发
      this.chart.map.off('highlight')
      this.chart.map.on('highlight', (params) => {
        if (params && params.batch && params.batch.length) {
          const batchItem = params.batch[0]
          const xIndex = batchItem.dataIndex
          this.$emit('selectedCallback', xIndex)
          this.getxAxisSelectData && this.getxAxisSelectData(xIndex)
        }
      })
    },
    showLoading() {
      this.chart.map.showLoading({
        color: '#12B9A3',
        fontFamily: 'PFZH',
        textColor: '#CCCCCC',
        fontSize: 14,
        lineWidth: 2
      }) // loading样式
    }
  }
}
</script>
<style lang="less" scoped>
.trend-box {
    height: 240px;
}
.echart_container {
    height: 240px;
}
</style>
